﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace P3SS.Networking
{
	/// <summary>
	/// Provides the base implementation of a protocol
	/// </summary>
	public abstract class AbstractProtocol
	{
		#region Fields
		/// <summary>
		/// Hostname of the server to connect to
		/// </summary>
		protected string server;
		/// <summary>
		/// Post of the server to connect to
		/// </summary>
		protected int port;
		/// <summary>
		/// Username to use when logging in to the server
		/// </summary>
		protected string username;
		/// <summary>
		/// Password to use when logging in to the server (in plaintext)
		/// </summary>
		protected string password;
		/// <summary>
		/// Type of encryption to use
		/// </summary>
		protected EncryptionType encryption;
		/// <summary>
		/// Holds the capabilities that the server reports
		/// </summary>
		protected string serverCapabilities;

		/// <summary>
		/// Handles interaction with network stream and encryption
		/// </summary>
		protected InnerProtocol innerProtocol;
		#endregion
		#region Properties
		/// <summary>
		/// Hostname of the server to connect to
		/// </summary>
		public string Server
		{
			get
			{ return server; }
			set
			{ server = value; }
		}

		/// <summary>
		/// Post of the server to connect to
		/// </summary>
		public int Port
		{
			get
			{ return port; }
			set
			{ port = value; }
		}

		/// <summary>
		/// Username to use when logging in to the server
		/// </summary>
		public string Username
		{
			get
			{ return username; }
			set
			{ username = value; }
		}

		/// <summary>
		/// Password to use when logging in to the server (in plaintext)
		/// </summary>
		public string Password
		{
			get
			{ return password; }
			set
			{ password = value; }
		}

		/// <summary>
		/// Type of encryption to use
		/// </summary>
		public EncryptionType Encryption
		{
			get
			{ return encryption; }
			set
			{ encryption = value; }
		}

		/// <summary>
		/// The capabilities of the server as reported by the server
		/// </summary>
		public string ServerCapabilities
		{
			get
			{ return serverCapabilities; }
		}
		#endregion
		#region Public Methods
		/// <summary>
		/// Checks that all settings are valid
		/// </summary>
		/// <returns>True if all settings are valid, otherwise false</returns>
		public virtual bool ValidateSettings()
		{
			bool isValid = true;

			isValid &= !string.IsNullOrEmpty(server);
			isValid &= ((port > 0) && (port < 65536));

			return isValid;
		}

		/// <summary>
		/// Compares this AbstractProtocol to another AbstractProtocol
		/// </summary>
		/// <param name="obj">AbstractProtocol to compare</param>
		/// <returns>True if all properties are equal, otherwise false</returns>
		public override bool Equals(object obj)
		{
			bool isEquals = false;

			if (obj.GetType() == this.GetType())
			{
				AbstractProtocol otherProtocol = (AbstractProtocol)obj;

				if ((server == otherProtocol.Server) && (port == otherProtocol.Port) && (username == otherProtocol.Username) && (password == otherProtocol.Password) && (encryption == otherProtocol.Encryption))
				{
					isEquals = true;
				}
			}

			return isEquals;
		}

		/// <summary>
		/// Creates a unique ID for this object
		/// </summary>
		/// <returns></returns>
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}
		#endregion
	}
}
